package com.ge.utils;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.ge.common.utils.AliPayUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class ALiYunPay {

    /**
     * 支付测试
     */
    public void addPay() {
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient(AliPayUtils.URL, AliPayUtils.APP_ID, AliPayUtils.APP_PRIVATE_KEY, AliPayUtils.FORMAT, AliPayUtils.CHARSET, AliPayUtils.ALIPAY_PUBLIC_KEY, AliPayUtils.SIGN_TYPE);
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("我是测试数据");
        model.setSubject("App支付测试Java");
        model.setOutTradeNo("这是订单号");
        model.setTimeoutExpress("30m");
        model.setTotalAmount("0.01");
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl("商户外网可以访问的异步地址");
        //验签
//        AlipaySignature.rsaCheckV1()
        try {
            AlipayTradeCloseRequest request1 = new AlipayTradeCloseRequest();
            AlipayTradeCloseResponse asd = alipayClient.sdkExecute(request1);
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            System.out.println(">>>>>>>>"+response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }

    /**
     * 异步回调地址
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping("/alipayPayNotify")
    public String alipayPayNotify(HttpServletRequest request) throws IOException {
        //获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        try {
            boolean flag = AlipaySignature.rsaCheckV1(params, AliPayUtils.ALIPAY_PUBLIC_KEY, AliPayUtils.CHARSET, AliPayUtils.SIGN_TYPE);
            //状态TRADE_SUCCESS的通知触发条件是商户签约的产品支持退款功能的前提下，买家付款成功；
            //交易状态TRADE_FINISHED的通知触发条件是商户签约的产品不支持退款功能的前提下，买家付款成功；或者，商户签约的产品支持退款功能的前提下，交易已经成功并且已经超过可退款期限。
            if (!params.get("app_id").equals("alipayAppId")) {
                return "failure";
            }
            if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                new Thread(() -> {
//                    shareOrderService.donePay(params.get("out_trade_no"), Orders.PAYTYPE_ZFB); //完成支付
                }).start();
            }
            return "success";
        } catch (AlipayApiException e) {
//            LOGGER.error("支付宝回调验证错误,错误码{},错误消息{}", e.getErrCode(), e.getErrMsg());
            return "failure";
        }
    }

    public static void main(String[] args) {
        ALiYunPay aLiYunPay = new ALiYunPay();
        aLiYunPay.addPay();
    }

}
